package com.huawei.boss.scripts;

import java.io.IOException;

import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

import com.huawei.boss.lang.Systems;

public class LuaSimple {
    public static void main(String[] args) throws IOException {
        String pt = Systems.is64BitEnv() ? "x64" : "x86";
        Systems.addJavaLibpath("./libs/jnlua-0.9.1/Win32-" + pt);
        // Acquire a script engine manager 
        //System.out.println(System.getProperty("java.library.path"));
        
        ScriptEngineManager manager = new ScriptEngineManager();

        // Get a script engine by name 
        ScriptEngine engine = manager.getEngineByName("Lua");

        // Populate the engine with some objects 
        String name = "Lua";
        StringBuilder sb = new StringBuilder();
        engine.put("name", name);
        engine.put("sb", sb);

        // Evaluate a script 
        try {
            Object nameFromEngine = engine.eval("return name");
            System.out.println("The name of the language is " + nameFromEngine);
        } catch (ScriptException e) {
            e.printStackTrace();
        }

        // Evaluate a script generated via the factory 
        try {
            String methodCall = engine.getFactory().getMethodCallSyntax("sb", "append", "name");
            engine.eval(methodCall); // evaluates 'sb:append(name)' 
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        System.out.println("The string builder says " + sb.toString());

        // Pre-compile a script and evaluate it repeatedly 
        Compilable compilable = (Compilable) engine;
        try {
            CompiledScript compiledScript = compilable.compile("return name");
            for (int i = 0; i < 3; i++) {
                Object nameFromEngine = compiledScript.eval();
                System.out.println("The name of the language is still " + nameFromEngine);
            }
        } catch (ScriptException e) {
            e.printStackTrace();
        }

        // Invoke a function 
        Invocable invocable = (Invocable) engine;
        try {
            invocable.invokeFunction("print", "Lua is Lua");
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // Let Lua implement an interface... 
        try {
            engine.eval("runnable = { run = function () print(\"This is Lua\") end }");
            Object luaRunnable = engine.get("runnable");
            Runnable runnable = invocable.getInterface(luaRunnable, Runnable.class);

            // ... and run it from another thread 
            Thread thread = new Thread(runnable);
            thread.start();
            thread.join();
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}